diff options
| author | Factiven <[email protected]> | 2023-12-24 13:03:54 +0700 |
|---|---|---|
| committer | Factiven <[email protected]> | 2023-12-24 13:03:54 +0700 |
| commit | 50a0f0240d7fef133eb5acc1bea2b1168b08e9db (patch) | |
| tree | 307e09e505580415a58d64b5fc3580e9235869f1 /pages/en/anime/watch/[...info].js | |
| parent | Update README.md (#104) (diff) | |
| download | moopa-50a0f0240d7fef133eb5acc1bea2b1168b08e9db.tar.xz moopa-50a0f0240d7fef133eb5acc1bea2b1168b08e9db.zip | |
migrate to typescript
Diffstat (limited to 'pages/en/anime/watch/[...info].js')
| -rw-r--r-- | pages/en/anime/watch/[...info].js | 213 |
1 files changed, 154 insertions, 59 deletions
diff --git a/pages/en/anime/watch/[...info].js b/pages/en/anime/watch/[...info].js index beab366..dc1f412 100644 --- a/pages/en/anime/watch/[...info].js +++ b/pages/en/anime/watch/[...info].js @@ -1,5 +1,4 @@ -import React, { useEffect, useRef, useState } from "react"; -import PlayerComponent from "@/components/watch/player/playerComponent"; +import { useEffect, useState } from "react"; import { FlagIcon, ShareIcon } from "@heroicons/react/24/solid"; import Details from "@/components/watch/primary/details"; import EpisodeLists from "@/components/watch/secondary/episodeLists"; @@ -9,13 +8,16 @@ import { authOptions } from "../../../api/auth/[...nextauth]"; import { createList, createUser, getEpisode } from "@/prisma/user"; import Link from "next/link"; import MobileNav from "@/components/shared/MobileNav"; -import { NewNavbar } from "@/components/shared/NavBar"; +import { Navbar } from "@/components/shared/NavBar"; import Modal from "@/components/modal"; import AniList from "@/components/media/aniList"; import { signIn } from "next-auth/react"; import BugReportForm from "@/components/shared/bugReport"; import Skeleton from "react-loading-skeleton"; import Head from "next/head"; +import VidStack from "@/components/watch/new-player/player"; +import { useRouter } from "next/router"; +import { Spinner } from "@vidstack/react"; export async function getServerSideProps(context) { let userData = null; @@ -81,7 +83,7 @@ export async function getServerSideProps(context) { color } synonyms - + } } `, @@ -91,6 +93,8 @@ export async function getServerSideProps(context) { }), }); const data = await ress.json(); + // const variables = { id: aniId }; + // const data = await getAnilistMediaInfo(variables, context.req); try { if (session) { @@ -142,17 +146,24 @@ export default function Watch({ const [episodesList, setepisodesList] = useState(); const [mapEpisode, setMapEpisode] = useState(null); - const [episodeSource, setEpisodeSource] = useState(null); - const [open, setOpen] = useState(false); const [isOpen, setIsOpen] = useState(false); + const { setAutoNext } = useWatchProvider(); + const [onList, setOnList] = useState(false); - const { theaterMode, setPlayerState, setAutoPlay, setMarked } = - useWatchProvider(); + const router = useRouter(); - const playerRef = useRef(null); + const { + theaterMode, + setPlayerState, + setAutoPlay, + setMarked, + setTrack, + aspectRatio, + setDataMedia, + } = useWatchProvider(); useEffect(() => { async function getInfo() { @@ -160,6 +171,8 @@ export default function Watch({ setOnList(true); } + setDataMedia(info); + const response = await fetch( `/api/v2/episode/${info.id}?releasing=${ info.status === "RELEASING" ? "true" : "false" @@ -202,17 +215,18 @@ export default function Watch({ const previousEpisode = episodeList?.find( (i) => i.number === parseInt(epiNumber) - 1 ); - setEpisodeNavigation({ + const vidNav = { prev: previousEpisode, playing: { id: currentEpisode.id, - title: playingData?.title, + title: playingData?.title || info?.title?.romaji, description: playingData?.description, img: playingData?.img || playingData?.image, number: currentEpisode.number, }, next: nextEpisode, - }); + }; + setEpisodeNavigation(vidNav); } } @@ -228,12 +242,17 @@ export default function Watch({ }, [sessions?.user?.name, epiNumber, dub]); useEffect(() => { + const autoNext = localStorage.getItem("autoNext"), + autoPlay = localStorage.getItem("autoplay"); + if (autoNext) { + setAutoNext(autoNext); + } + if (autoPlay) { + setAutoPlay(autoPlay); + } + async function fetchData() { if (info) { - const autoplay = - localStorage.getItem("autoplay_video") === "true" ? true : false; - setAutoPlay(autoplay); - const anify = await fetch("/api/v2/source", { method: "POST", headers: { @@ -252,6 +271,11 @@ export default function Watch({ }), }).then((res) => res.json()); + if (!anify?.sources?.length > 0) { + router.push(`/en/anime/${info.id}?notfound=true`); + return; + } + const skip = await fetch( `https://api.aniskip.com/v2/skip-times/${info.idMal}/${parseInt( epiNumber @@ -267,31 +291,77 @@ export default function Watch({ return res.json(); }); - const op = - skip?.results?.find((item) => item.skipType === "op") || null; - const ed = - skip?.results?.find((item) => item.skipType === "ed") || null; + let getOp = + skip?.results?.find((item) => item.skipType === "op") || null, + getEd = skip?.results?.find((item) => item.skipType === "ed") || null; + + const op = getOp + ? { + startTime: + anify?.intro?.start ?? Math.round(getOp?.interval.startTime), + endTime: + anify?.intro?.end ?? Math.round(getOp?.interval.endTime), + text: "Opening", + } + : null, + ed = { + startTime: + anify?.outro?.start ?? Math.round(getEd?.interval.startTime), + endTime: anify?.outro?.end ?? Math.round(getEd?.interval.endTime), + text: "Ending", + }; + const skipData = [op, ed].filter((i) => i !== null); + + const quality = + anify?.sources?.find( + (i) => i.quality === "default" || i.quality === "auto" + ) || anify?.sources[0]; + + const reFormSubtitles = anify?.subtitles?.map((i) => { + return { + src: proxy + "/" + i.url, + label: i.lang, + kind: i.lang === "Thumbnails" ? "thumbnails" : "subtitles", + ...(i.lang === "English" && { default: true }), + }; + }); + + const thumbnails = reFormSubtitles?.find( + (i) => i.kind === "thumbnails" + ); + + const subtitles = reFormSubtitles?.filter( + (i) => i.kind !== "thumbnails" + ); const episode = { - epiData: anify, - skip: { - op, - ed, + provider, + isDub: dub, + defaultQuality: { + // url: quality?.url, + url: `${proxy}/proxy/m3u8/${encodeURIComponent( + String(quality?.url) + )}/${encodeURIComponent(JSON.stringify(anify?.headers))}`, + headers: anify?.headers, }, + subtitles: subtitles, + thumbnails: thumbnails?.src, + epiData: anify, + skip: skipData, }; - setEpisodeSource(episode); + setTrack(episode); } } fetchData(); return () => { - setEpisodeSource(); setPlayerState({ currentTime: 0, isPlaying: false, }); setMarked(0); + setTrack(null); }; // eslint-disable-next-line react-hooks/exhaustive-deps @@ -424,7 +494,7 @@ export default function Watch({ </Modal> <BugReportForm isOpen={isOpen} setIsOpen={setIsOpen} /> <main className="w-screen h-full"> - <NewNavbar + <Navbar scrollP={20} withNav={true} shrink={true} @@ -435,21 +505,23 @@ export default function Watch({ className={`mx-auto pt-16 ${theaterMode ? "lg:pt-16" : "lg:pt-20"}`} > {theaterMode && ( - <PlayerComponent - id={"cinematic"} - session={sessions} - playerRef={playerRef} - dub={dub} - info={info} - watchId={watchId} - proxy={proxy} - track={episodeNavigation} - data={episodeSource?.epiData} - skip={episodeSource?.skip} - timeWatched={userData?.timeWatched} - provider={provider} - className="w-screen max-h-[85dvh]" - /> + <div + className={`bg-black w-full max-h-[84dvh] h-full flex-center rounded-md`} + style={{ aspectRatio: aspectRatio }} + > + {episodeNavigation ? ( + <VidStack + id={`${watchId}-theater`} + navigation={episodeNavigation} + sessions={sessions} + userData={userData} + /> + ) : ( + <div className="flex-center aspect-video w-full h-full relative"> + <SpinLoader /> + </div> + )} + </div> )} <div id="default" @@ -459,20 +531,25 @@ export default function Watch({ > <div id="primary" className="w-full"> {!theaterMode && ( - <PlayerComponent - id={"default"} - session={sessions} - playerRef={playerRef} - dub={dub} - info={info} - watchId={watchId} - proxy={proxy} - track={episodeNavigation} - data={episodeSource?.epiData} - skip={episodeSource?.skip} - timeWatched={userData?.timeWatched} - provider={provider} - /> + <div + className={`bg-black w-full flex-center rounded-md overflow-hidden ${ + aspectRatio === "4/3" ? "aspect-video" : "" + }`} + // style={{ aspectRatio: aspectRatio }} + > + {episodeNavigation ? ( + <VidStack + id={`${watchId}-default`} + navigation={episodeNavigation} + sessions={sessions} + userData={userData} + /> + ) : ( + <div className="flex-center aspect-video w-full h-full relative"> + <SpinLoader /> + </div> + )} + </div> )} <div id="details" @@ -506,7 +583,7 @@ export default function Watch({ className="flex items-center gap-2 px-3 py-1 ring-[1px] ring-white/20 rounded overflow-hidden" > <ShareIcon className="w-5 h-5" /> - share + <span className="hidden lg:block">share</span> </button> <button type="button" @@ -514,11 +591,10 @@ export default function Watch({ className="flex items-center gap-2 px-3 py-1 ring-[1px] ring-white/20 rounded overflow-hidden" > <FlagIcon className="w-5 h-5" /> - report + <span className="hidden lg:block">report</span> </button> </div> </div> - {/* <div>right</div> */} </div> <Details @@ -538,6 +614,11 @@ export default function Watch({ id="secondary" className={`relative ${theaterMode ? "pt-5" : "pt-4 lg:pt-0"}`} > + {/* <div className="w-full h-[150px] text-black p-3"> + <span className="bg-white w-full h-full flex-center"> + ad banner + </span> + </div> */} <EpisodeLists info={info} session={sessions} @@ -556,3 +637,17 @@ export default function Watch({ </> ); } + +function SpinLoader() { + return ( + <div className="pointer-events-none absolute inset-0 z-50 flex h-full w-full items-center justify-center"> + <Spinner.Root + className="text-white animate-spin opacity-100" + size={84} + > + <Spinner.Track className="opacity-25" width={8} /> + <Spinner.TrackFill className="opacity-75" width={8} /> + </Spinner.Root> + </div> + ); +} |